import Phaser from "phaser";

interface customParamType {
  gameWidth: number;
  gameHeight: number;
  scoreRef: any;
  overRef: any;
}
/*
  1.初始化画布，尺寸适配
  2.加载资源
  3.设置物理边界
  4.设置刚体body（重力，弹力，质量），用于碰撞检测
  5.监听碰撞，判断相同类型水果触发合并
  6.播放合并动画，移除就旧水果生成新水果
  7.更新分数，判断是否是最大水果不升级
*/

// 水果类型和大小映射
const fruitTypes = [
  { name: 'passion', radius: 20, score: 1 },
  { name: 'cherry', radius: 25, score: 2 },
  { name: 'apple', radius: 30, score: 3 },
  { name: 'pear', radius: 35, score: 4 },
  { name: 'kiwi', radius: 40, score: 5 },
  { name: 'avocado', radius: 45, score: 6 },
  { name: 'pineapple', radius: 50, score: 7 },
  { name: 'pomelo', radius: 55, score: 8 },
  { name: 'durian', radius: 60, score: 9 },
  { name: 'watermelon', radius: 65, score: 10 }
];

export class MatchScene extends Phaser.Scene {
  private dragGroup: any = null;//可拖拽组，手指按住的水果
  private staticGroup: any = null;//不可拖拽组，已经落地的水果
  private currentFruit: any = null; // 当前水果
  private score: number = 0; // 分数
  private fruits: any[] = [];
  private defautPosition: any = { x: 0, y: 0 };
  public gameWidth: number;
  public gameHeight: number;
  public scoreRef: any;
  public overRef: any;
  private createFruitsQueue: any[] = []
  private isProcessingCreateQueue: boolean = false
  private mergeFruitsQueue: any[] = []
  private isProcessingMergeQueue: boolean = false
  private isDragging: boolean = false; // 新增标志位
  over: any; // 游戏是否结束

  constructor(config: Phaser.Types.Scenes.SettingsConfig, customParam: customParamType) {
    super(config);
    this.gameWidth = customParam.gameWidth;
    this.gameHeight = customParam.gameHeight;
    this.scoreRef = customParam.scoreRef;
    this.overRef = customParam.overRef;
  }

  preload(): void {
    // 预加载图片
    fruitTypes.forEach(fruit => {
      this.load.image(fruit.name, `/image/fruit/${fruit.name}.png`);
    });

    this.load.image('background', `/image/fruit/bg.png`);

    // 添加加载进度事件
    this.load.on('progress', (value: number) => {
      console.log('Loading progress:', value);
    });

    this.load.on('complete', () => {
      console.log('Loading complete');
    });

    this.load.on('loaderror', (file: any) => {
      console.error('Error loading file:', file);
    });
  }

  create(): void {
    console.log('Scene created, dimensions:', this.gameWidth, this.gameHeight);
    // 创建粒子发射器
    this.defautPosition = { x: this.scale.width / 2, y: 50 }
    // 设置背景图
    this.add.image(0, 0, 'background')
      .setOrigin(0)
      .setDisplaySize(this.scale.width, this.scale.height);
    // 启用调试渲染
    this.matter.world.drawDebug = true;
    // 不同组用颜色区分
    this.matter.world.debugShowCollisionFilters = true
    // 创建碰撞组
    this.dragGroup = this.matter.world.nextGroup()
    this.staticGroup = this.matter.world.nextGroup();

    // 创建边界（属于不可拖拽组）
    this.createBoundaries()

    // 创建西瓜时动态分配碰撞
    this.addCreateFruitsQueue();

    // mouseSpring 和 setInteractive + setDraggable对比
    // 添加鼠标约束（弹簧效果），允许用户拖动物体。拖拽时候会摆动（类似橡皮筋），如愤怒小鸟
    // stiffness：弹簧的刚度，范围是 0 到 1。数值越高，拖拽时物体越紧贴鼠标。collisionFilter 定义哪些物体可以被鼠标拖动。这里仅限于 canDrag 组的对象。
    // const mouseConstraint: any = this.matter.add.mouseSpring({
    //   stiffness: 0.8,
    //   collisionFilter: { group: this.dragGroup }
    // });
  }

  private createBoundaries() {

    // 创建边界（walls）
    const wallThickness = 50; // 墙壁厚度

    // 左右边界的墙壁
    this.matter.add.rectangle(0, this.scale.height / 2, wallThickness, this.scale.height, { isStatic: true });
    this.matter.add.rectangle(this.scale.width, this.scale.height / 2, wallThickness, this.scale.height, { isStatic: true });

    // 上下边界的墙壁
    this.matter.add.rectangle(this.scale.width / 2, 0, this.scale.width, wallThickness, { isStatic: true });
    this.matter.add.rectangle(this.scale.width / 2, this.scale.height, this.scale.width, wallThickness, { isStatic: true });

    // 设置标准矩形边界，需要防止拖拽穿透场景
    this.matter.world.setBounds(0, 0, this.scale.width, this.scale.height, { collisionFilter: { group: this.staticGroup } })//根据画布自动创捷边界，物体可以自由飞出屏幕外
    console.log(this.scale.width, this.scale.height);

  }

  async addCreateFruitsQueue() {
    const typeIndex = Phaser.Math.Between(0, 3);
    const fruitType = fruitTypes[typeIndex];
    // 将请求添加到队列中
    this.createFruitsQueue.push({ typeIndex, fruitType })
    // 如果当前没有在处理队列，则开始处理
    if (!this.isProcessingMergeQueue) {
      await this.createNewFruit()
    }
  }

  private async createNewFruit() {

    if (this.over) return;
    this.isProcessingCreateQueue = true
    try {
      while (this.createFruitsQueue.length > 0) {
        // 随机选择水果类型（初期限制为前几种）
        const { typeIndex, fruitType } = this.createFruitsQueue.shift();
        const texture = this.textures.get(fruitType.name);
        const frame = texture.get();
        const maxTextureDim = Math.max(frame.width, frame.height);
        this.currentFruit?.destroy();
        // 创建新水果
        // add.image(x,y,texture,frame,options)自动为图片创建匹配的矩形刚体。 x,y场景种坐标，texture是图片名称（必须加载完成）,frame动画可选帧编号，options设置body初始状态
        // chamfer圆角，setBounces设置物体弹性，setCollisionGroup分配碰撞组
        this.currentFruit = this.matter.add.image(this.defautPosition.x, this.defautPosition.y, fruitType.name, null, {
          shape: { type: 'circle', radius: maxTextureDim / 2 },
          chamfer: 0,
          restitution: 0.6, // 弹性系数，避免弹跳太夸张
          friction: 0.1,   // 摩擦系数 0.005
          mass: 1,          // 质量
          isStatic: false, // 确保是动态物体
        }).setBounce(0.3).setCollisionGroup(this.dragGroup);
        this.fruits.push(this.currentFruit);
        this.currentFruit.fruitType = fruitType;
        this.currentFruit.typeIndex = typeIndex;
        // 动态计算纹理缩放，使其等比适配半径范围
        const scale = (fruitType.radius * 2) / maxTextureDim;
        this.currentFruit.setScale(scale);

        // //setInteractive + setDraggable启用拖拽交互,能够响应玩家的输入事件（如点击、拖拽），精准控制需手动管理物理
        this.currentFruit.setInteractive();
        this.input.setDraggable(this.currentFruit);
        // phaser添加交互点击事件input.on(event, callback, context)，键盘input.keyboard.createCursorKeys()
        this.input.on('drag', (pointer, gameObject, dragX, dragY) => {
          if (gameObject === this.currentFruit) {
            gameObject.x = dragX;
            gameObject.y = this.defautPosition.y;
          }
        });

        this.input.on('dragstart', () => {
          console.log('Drag started');
          this.isDragging = true;
          this.currentFruit.setIgnoreGravity(true); //临时禁用重力对水果的影响，碰撞仍会有反应，保留阻挡其他物体
          // currentFruit.setSensor(true);// 拖拽时设为传感器（不产生物理反馈）,会碰撞但是无物理反应，其他物体会穿透
        });

        // 拖拽开始时锁定Y轴
        this.matter.world.on('beforeupdate', () => {
          if (this.currentFruit && this.currentFruit.body && this.currentFruit.body.isStatic == false) {
            // 保持 Y 坐标不变，只允许 X 移动
            this.currentFruit.y = 0;
          }
        });

        this.input.on('dragend', (pointer: any, gameObject: any) => {
          console.log('Drag ended', gameObject, this.currentFruit);
          if (!this.currentFruit || !this.currentFruit.body) {
            console.warn('currentFruit 不存在或已被销毁');
            return;
          }
          if (gameObject === this.currentFruit && this.isDragging) {
            this.currentFruit.setIgnoreGravity(false);
            this.currentFruit.setVelocity(0, 0); // 清除速度，保证下落一致性
            this.currentFruit.setCollisionGroup(this.staticGroup);
            // this.currentFruit.destroy(); //销毁会导致下落失效
            this.currentFruit = null;
            this.isDragging = false;
            this.isProcessingCreateQueue = false
            this.addCreateFruitsQueue();
          }
        });

        // 新增点击事件监听器
        this.input.on('pointerdown', (pointer: any, gameObject: any) => {
          if (!this.isDragging && !this.isProcessingCreateQueue) {
            console.log('Clicked without dragging');
            this.isProcessingCreateQueue = false;
            this.addCreateFruitsQueue();
          }
        });
      }
    } catch (error) {
      console.error("添加水果处理队列时出现异常:", error)
    }
  }
  
  addMergeFruitsQueue(fruit1: any, fruit2: any) {
    // 将请求添加到队列中
    this.mergeFruitsQueue.push({ fruit1, fruit2 })
    // 如果当前没有在处理队列，则开始处理
    if (!this.isProcessingMergeQueue) {
      this.mergeFruits()
    }
  }
  private mergeFruits() {
    if (this.over) return;
    this.isProcessingMergeQueue = true
    try {
      while (this.mergeFruitsQueue.length > 0) {
        const { fruit1, fruit2 } = this.mergeFruitsQueue.shift();
        // 创建新水果
        const newTypeIndex: any = fruit1.typeIndex + 1;
        const newFruitType: any = fruitTypes[newTypeIndex];

        const x = (fruit1.x + fruit2.x) / 2;
        const y = (fruit1.y + fruit2.y) / 2;

        // 移除原来的水果
        fruit1.destroy();
        fruit2.destroy();

        const texture = this.textures.get(newFruitType.name);
        const frame = texture.get();
        const maxTextureDim = Math.max(frame.width, frame.height);

        const newFruit: any = this.matter.add.image(x, y, newFruitType.name, null, {
          shape: { type: 'circle', radius: maxTextureDim / 2 },
          chamfer: 0,
          restitution: 0.6, // 弹性系数，避免弹跳太夸张
          friction: 0.1,   // 摩擦系数 0.005
          mass: 1,          // 质量
          isStatic: false, // 确保是动态物体
        }).setBounce(0.3).setCollisionGroup(this.dragGroup);;

        newFruit.fruitType = newFruitType;
        newFruit.typeIndex = newTypeIndex;

        // 动态计算纹理缩放，使其等比适配半径范围
        const scale = (newFruitType.radius * 2) / maxTextureDim;
        newFruit.setScale(scale);

        // 增加分数
        this.score += newFruitType.score;
        this.updateScore(this.score)
        // this.checkGameOver()

        // // 创建第一个粒子发射器（红色）
        // const emitter1 = this.add.particles(100, 300, 'particleTexture', {
        //   speed: 100,
        //   lifespan: 2000,
        //   scale: { start: 0.5, end: 0 },
        //   blendMode: 'ADD',  // 叠加混合模式增强视觉效果
        //   emitting: false
        // });
        // // 创建第二个粒子发射器（蓝色）
        // const emitter2 = this.add.particles(700, 300, 'particleTexture', {
        //   speed: 100,
        //   lifespan: 2000,
        //   scale: { start: 0.5, end: 0 },
        //   blendMode: 'ADD',
        //   emitting: false
        // });
        // // 设置粒子发射方向（向中间发射）
        // emitter1.setAngle({ min: -20, max: 20 });
        // emitter2.setAngle({ min: 160, max: 200 });

        // // 启动发射器
        // emitter1.start();
        // emitter2.start();
        // 处理完队列后标记为未处理状态
        this.isProcessingMergeQueue = false
      }
    } catch (error) {
      console.error("合并水果处理队列时出现异常:", error)
    }
  }
  updateScore(score: number) {
    console.log('更新分数：', score);
    this.scoreRef.textContent = score;
  }

  private checkGameOver() {
    this.fruits?.forEach(fruit => {
      console.log('checkGameOver', fruit);
      // if (fruit.y < 600) {
      //   // 游戏结束逻辑
      //   this.over = true
      //   this.scene.pause();
      //   this.overRef.visible = true;
      // }
    });
  }
  update(): void {
    const self = this
    // 游戏循环更新逻辑
    if (!this.currentFruit) return;

    // 检测碰撞
    this.matter.world.on('collisionstart', function (event: any, bodyA: any, bodyB: any) {
      const fruitA = bodyA.gameObject;
      const fruitB = bodyB.gameObject;

      if (fruitA && fruitB && fruitA.fruitType && fruitB.fruitType) {
        // 相同类型水果碰撞
        if (fruitA.typeIndex === fruitB.typeIndex) {
          // 检查是否可以合成更大的水果
          if (fruitA.typeIndex < fruitTypes.length - 1) {
            self.addMergeFruitsQueue(fruitA, fruitB)
          }
        }
      }
    }, this);
  }
} 